<html>
<body>
<H2><center>TDD harness for native C++</center></H2>
<P>To use, #include "tdd.h" in your test code, build a test dll and run either the console test runner or the gui test runner.</P>

<table cellpadding="2" cellspacing="1">
 <tr><td><b>folder</b></td><td><b>readme file</b>(if any)</td><td><b>Contents of each folder</b></td></tr>
 <tr><td><a href="file://\\tkfiltoolbox\tools\23791\v3.1\">.</a></td><td> </td><td>the all-important "tdd.h" header file, this readme.txt and a VS2008 solution</td></tr>
 <tr><td><a href="file://\\tkfiltoolbox\tools\23791\v3.1\tddDll">.\tddDll</a></td><td><a href="tddDll\readme.html">readme.html</a></td><td>everything you need to build a test dll (including instructions):  the .def file, a .cpp containing a single exported function</td></tr>
 <tr><td><a href="file://\\tkfiltoolbox\tools\23791\v3.1\tddGui">.\tddGui</a></td><td><a href="tddGui\readme.html">readme.html</a></td><td>the gui test runner</td></tr>
 <tr><td><a href="file://\\tkfiltoolbox\tools\23791\v3.1\tddGui\TddGuiTests">.\tddGui\TddGuiTests</a></td><td> </td><td>unit tests for the gui test runner (demonstrates how to do TDD on UI)</td></tr>
 <tr><td><a href="file://\\tkfiltoolbox\tools\23791\v3.1\tddConsole">.\tddConsole</a></td><td><a href="tddConsole\readme.html">readme.html</a></td><td>the console test runner</td></tr>
 <tr><td><a href="file://\\tkfiltoolbox\tools\23791\v3.1\tddConsole\unittests">.\tddConsole\unittests</a></td><td> </td><td>unit tests for the console test runner, plus example tests (see Example below)</td></tr>
 <tr><td><a href="file://\\tkfiltoolbox\tools\23791\v3.1\tddAssertTests">.\tddAssertTests</a></td><td><a href="tddAssertTests\readme.html">readme.html</a></td><td>tests for a handy assert class, if you can take a dependency on ATL's CString class</td></tr>
</table>

</P>Here's an example of a few tests (taken from tddConsole\unittests\ExampleTests.cpp):</P>

<PRE>
<b style="color:blue;background-color:#ffffff">#include</b><b style="color:brown;background-color:#ffffff"> "stdafx.h"</b> <b style="color:green;background-color:#ffffff">// include standard stuff, like tdd.h, tddAssert.h (if you can use ATL), windows.h, etc.</b>
<b style="color:blue;background-color:#ffffff">#include</b><b style="color:brown;background-color:#ffffff"> "ExampleClass.h"</b> <b style="color:green;background-color:#ffffff">// header for the example class we want to test</b>

<b style="color:blue;background-color:#ffffff">namespace</b> SomeNamespaceUsedForGroupingTests <b style="color:green;background-color:#ffffff">// this will show up in the gui test runner's treeview as a top-level item</b>
{
<b style="color:blue;background-color:#ffffff">namespace</b> AnotherDeeperNamespace <b style="color:green;background-color:#ffffff">// this will show up in the gui test runner's treeview as a child of SomeNamespaceUsedForGroupingTests</b>
{
TESTCLASS(ExampleClassTests) <b style="color:green;background-color:#ffffff">// a class to hold a bunch of tests.  It's a real class - you can inherit from other classes, have data members, etc.</b>
{
    ExampleClass* m_pEC; <b style="color:green;background-color:#ffffff">// an example class that tests for primality</b>
<b style="color:blue;background-color:#ffffff">public:</b>
    ExampleClassTests() : m_pEC(NULL) {} <b style="color:green;background-color:#ffffff">// constructors should either be empty or at least run very fast...</b>

<b style="color:blue;background-color:#ffffff">private:
    virtual void</b> TestInitialize() <b style="color:green;background-color:#ffffff">// ... lazy initialization goes here.  This is called before each test method is run.</b>
    {
        m_pEC = <b style="color:blue;background-color:#ffffff">new</b> ExampleClass;
    }
<b style="color:blue;background-color:#ffffff">    virtual void</b> TestCleanup() <b style="color:green;background-color:#ffffff">// this is called after each test method is run.</b>
    {
        <b style="color:blue;background-color:#ffffff">delete</b> m_pEC;
    }
    <b style="color:green;background-color:#ffffff">// also available are ClassInitialize() and ClassCleanup() which are run once before and once after all the test methods are run, respectively.</b>

<b style="color:blue;background-color:#ffffff">private:</b> <b style="color:green;background-color:#ffffff">// or public, as you please</b>
    TESTMETHOD(Is2Prime) <b style="color:green;background-color:#ffffff">// a test method</b>
    {
        m_pEC->Set(2);
        TddAssert().IsTrue(m_pEC->IsPrime(), L<b style="color:brown;background-color:#ffffff">"2 is prime"</b>);
    }
    TESTMETHOD(Is3Prime) <b style="color:green;background-color:#ffffff">// another</b>
    {
        m_pEC->Set(3);
        TddAssert().IsTrue(m_pEC->IsPrime(), L<b style="color:brown;background-color:#ffffff">"3 is prime"</b>);
    }
    TESTMETHOD(Is4Prime)
    {
        m_pEC->Set(4);
        TddAssert().IsFalse(m_pEC->IsPrime(), L<b style="color:brown;background-color:#ffffff">"4 is not prime"</b>);
    }

    TESTMETHOD(SetNotCalledTest)
    {
        TddAssert().IsFalse(m_pEC->IsPrime(), L<b style="color:brown;background-color:#ffffff">"-1 is not prime"</b>);
    }

    <b style="color:green;background-color:#ffffff">// a whole bunch of tests, showing refactorability</b>
    TESTMETHOD(Test5ForPrimality)  { RefactoredTest( 5, <b style="color:blue;background-color:#ffffff">true</b>,  L<b style="color:brown;background-color:#ffffff">"5 is prime"</b>); }
    TESTMETHOD(Test6ForPrimality)  { RefactoredTest( 6, <b style="color:blue;background-color:#ffffff">false</b>, L<b style="color:brown;background-color:#ffffff">"6 is not prime"</b>); }
    TESTMETHOD(Test7ForPrimality)  { RefactoredTest( 7, <b style="color:blue;background-color:#ffffff">true</b>,  L<b style="color:brown;background-color:#ffffff">"7 is prime"</b>); }
    TESTMETHOD(Test8ForPrimality)  { RefactoredTest( 8, <b style="color:blue;background-color:#ffffff">false</b>, L<b style="color:brown;background-color:#ffffff">"8 is not prime"</b>); }
    TESTMETHOD(Test9ForPrimality)  { RefactoredTest( 9, <b style="color:blue;background-color:#ffffff">false</b>, L<b style="color:brown;background-color:#ffffff">"9 is not prime"</b>); }
    TESTMETHOD(Test10ForPrimality) { RefactoredTest(10, <b style="color:blue;background-color:#ffffff">false</b>, L<b style="color:brown;background-color:#ffffff">"10 is not prime"</b>); }
    TESTMETHOD(Test11ForPrimality) { RefactoredTest(11, <b style="color:blue;background-color:#ffffff">true</b>,  L<b style="color:brown;background-color:#ffffff">"11 is prime"</b>); }
    TESTMETHOD(Test12ForPrimality) { RefactoredTest(12, <b style="color:blue;background-color:#ffffff">false</b>, L<b style="color:brown;background-color:#ffffff">"12 is not prime"</b>); }
    TESTMETHOD(Test13ForPrimality) { RefactoredTest(13, <b style="color:blue;background-color:#ffffff">true</b>,  L<b style="color:brown;background-color:#ffffff">"13 is prime"</b>); }
    TESTMETHOD(Test14ForPrimality) { RefactoredTest(14, <b style="color:blue;background-color:#ffffff">false</b>, L<b style="color:brown;background-color:#ffffff">"14 is not prime"</b>); }
    TESTMETHOD(Test15ForPrimality) { RefactoredTest(15, <b style="color:blue;background-color:#ffffff">false</b>, L<b style="color:brown;background-color:#ffffff">"15 is not prime"</b>); }
    TESTMETHOD(Test16ForPrimality) { RefactoredTest(16, <b style="color:blue;background-color:#ffffff">false</b>, L<b style="color:brown;background-color:#ffffff">"16 is not prime"</b>); }
    TESTMETHOD(Test17ForPrimality) { RefactoredTest(17, <b style="color:blue;background-color:#ffffff">true</b>,  L<b style="color:brown;background-color:#ffffff">"17 is prime"</b>); }
    TESTMETHOD(Test18ForPrimality) { RefactoredTest(18, <b style="color:blue;background-color:#ffffff">false</b>, L<b style="color:brown;background-color:#ffffff">"18 is not prime"</b>); }

    TESTMETHOD(KnownBigPrime)      { RefactoredTest(15487457, <b style="color:blue;background-color:#ffffff">true</b>, L<b style="color:brown;background-color:#ffffff">"15487457 is prime"</b>); }

    TESTMETHOD(TestNegativeNumber) { RefactoredTest(-1, <b style="color:blue;background-color:#ffffff">false</b>, L<b style="color:brown;background-color:#ffffff">"-1 is not prime"</b>); }
    TESTMETHOD(TestZero)           { RefactoredTest (0, <b style="color:blue;background-color:#ffffff">false</b>, L<b style="color:brown;background-color:#ffffff">"0 is not prime"</b>); }
    TESTMETHOD(TestOne)            { RefactoredTest (1, <b style="color:blue;background-color:#ffffff">false</b>, L<b style="color:brown;background-color:#ffffff">"1 is not prime"</b>); }

<b style="color:blue;background-color:#ffffff">private:</b>
    void RefactoredTest(<b style="color:blue;background-color:#ffffff">int</b> i, <b style="color:blue;background-color:#ffffff">bool</b> b, <b style="color:blue;background-color:#ffffff">const</b> WCHAR* hint)
    {
        m_pEC->Set(i);
        TddAssert().AreEqual(b, m_pEC->IsPrime(), hint);
    }
};
}
}
</PRE>

<HR />
<H3>Additional notes:</H3>
<HR />
<P>A <a style="font-family:fixedsys">TESTCLASS</a> is a real class and so can have additional bases, data members and other methods.  For example:</P>

<PRE>
<b style="color:blue;background-color:#ffffff">class</b> SomeBase
{
<b style="color:blue;background-color:#ffffff">public:</b>
    <b style="color:blue;background-color:#ffffff">void</b> SomeMethod() { <b style="color:green;background-color:#ffffff">/* ... */</b> }
};
TESTCLASS(AnotherClassTests), <b style="color:blue;background-color:#ffffff">private</b> SomeBase
{
    <b style="color:blue;background-color:#ffffff">virtual void</b> TestInitialize()
    {
        SomeMethod();
    }
};
</PRE>

<HR />
<P>Constructors of <a style="font-family:fixedsys">TESTCLASS</a>es should be empty or very fast. This is necessary because behinds the scenes a global instance of each <a style="font-family:fixedsys">TESTCLASS</a> is instantiated whether you want to run tests in that class or not (we don't know yet what tests you want to run). Any non-trivial initialization should happen in the <a style="font-family:fixedsys">TestInitialize()</a> method.</P>
<HR />
</body>
</html>